﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace SkillSystem
{
    /// <summary>
    /// 技能发射器基类
    /// </summary>
    public abstract class TransmitterBase :ISkillTransmitter
    {
        public SkillState CurSkillState = SkillState.End;

        protected IDamageTrigger damageTrigger;

        public Animator CurAnimator;

        public Dictionary<SkillProcesserType, ISkillItemProcesser> SkillProcessers { get; private set; }

        public SkillItem[] SkillItems;

        public SkillItem CurSkillItem { get { return SkillItems[curSkillIndex]; } }

        public SkillItem LastSkillDynamicData {
            get {
                if (curSkillIndex - 1>=0)
                {
                    return SkillItems[curSkillIndex - 1];
                }
                return null;
            }
        }

        public int SkillID
        {
            get
            {
                return curSkillData.ID;
            }
        }

        protected SkillData curSkillData;

        protected int curSkillIndex=0;
        

        protected SyncContainer<ISkillItemProcesser> processerSync ;

        protected SyncContainer<ISkillItemProcesser> processerPerTriggerSync;


        public TransmitterBase(SkillData data, Animator anim)
        {
            curSkillData = data;
            CurAnimator = anim;
            InitData(data);
            processerSync = new SyncContainer<ISkillItemProcesser>(OnSkillItemComplete,null);
            processerPerTriggerSync = new SyncContainer<ISkillItemProcesser>(null, null);
            SkillProcessers = new Dictionary<SkillProcesserType, ISkillItemProcesser>();

            InitProcesser();

            damageTrigger = new DamageTrigger(this);
        }

        protected virtual void InitProcesser()
        {
            SkillProcessers.Add(SkillProcesserType.Animation, new SkillAnimationProcesser(this, CurAnimator));
            SkillProcessers.Add(SkillProcesserType.Effect, new SkillEffectProcesser(this, CurAnimator.transform));

            //SkillProcessers.Add(SkillProcesserType.Time, new SkillTimeProcesser());
            //SkillProcessers.Add(SkillProcesserType.CameraShake, new SkillCameraShakeProcesser());


            foreach (var item in SkillProcessers)
            {
                processerSync.Add(item.Value);
            }


        }

        protected void InitData(SkillData data)
        {
            curSkillIndex = 0;
            SkillItems = new SkillItem[data.SkillItems.Count];
            for (int i = 0; i < data.SkillItems.Count; i++)
            {
                SkillItemData itemData = SkillSystemFacade.Inst.GetSkillItemData(data.SkillItems[i]);
                
                if (itemData != null)
                {
                    SkillItem dynamicData = new SkillItem(itemData);
                    SkillItems[i] = dynamicData;
                }
                else
                {
                    DebugUtils.LogError(data.Name + " 技能配置出错 ID" + data.SkillItems[i] + "不存在");
                }
            }
        }

        protected virtual bool CheckTransmitCondition()
        {
            return true;
        }

        protected virtual bool CheckItemCondition()
        {
            bool isOk = true;
            foreach (var linker in CurSkillItem.Linkers)
            {
                if (!linker.Value.IsCanLinkToNextItem())
                {
                    isOk = false;
                }
            }
            
            return isOk;
        }

        public void SwitchSkill(SkillData data)
        {
            curSkillData = data;
            InitData(curSkillData);
        }
        
        public virtual void StopTransmit()
        {
            curSkillIndex = SkillItems.Length;
            processerSync.Break();
        }

        /// <summary>
        /// 触发技能
        /// </summary>
        public virtual void StartTransmit()
        {
            processerPerTriggerSync.Do();

            if (CurSkillState == SkillState.End)
            {
                if (!CheckTransmitCondition())
                {
                    return;
                }
                else
                {
                    CurSkillState = SkillState.Excuting;
                    processerSync.Do();
                }
                return;
            }
        }

        private void OnSkillItemComplete()
        {
            PreSkillItemCompleted();

            if (curSkillIndex+1>= SkillItems.Length)
            {
                CurSkillState= SkillState.End;
                curSkillIndex = 0;
                foreach (var item in SkillProcessers)
                {
                    item.Value.OnSkillCompleted();
                }
            }
            else
            {
                CurSkillItem.State = SkillItemState.End;

                bool isOk = CheckItemCondition();
                foreach (var linker in CurSkillItem.Linkers)
                {
                    linker.Value.OnSkillItemCompleted();
                }

                if (!isOk)
                {
                    if (CurSkillItem.CurSkillItemData.IsNoLinkWillBreak)
                    {
                        StopTransmit();
                    }
                }
                else
                {
                    curSkillIndex++;
                    processerSync.Do();
                }

            }
            AfterSkillItemCompleted();
        }

        protected virtual void PreSkillItemCompleted()
        {

        }

        protected virtual void AfterSkillItemCompleted()
        {

        }
    }
}
